//! 后台工作线程
//!
//! 负责从消息队列接收日志事件并写入目标 Appender。
//!
//! ## 主要类型
//!
//! - [`Worker`] - 后台工作线程
//! - [`WorkerConfig`] - 工作线程配置
//!
//! ## 示例
//!
//! ```rust,ignore
//! use log4r::async_rt::{LogChannel, Worker, WorkerConfig};
//! use log4r::appender::ConsoleAppender;
//! use std::sync::Arc;
//!
//! // 创建通道和 Appender
//! let channel = LogChannel::new(1000);
//! let appender = Arc::new(ConsoleAppender::stdout());
//!
//! // 启动 Worker
//! let worker = Worker::start(
//!     channel.receiver().clone(),
//!     vec![appender],
//!     WorkerConfig::default(),
//! );
//!
//! // 关闭 Worker
//! worker.shutdown().unwrap();
//! ```

use std::panic::AssertUnwindSafe;
use std::sync::Arc;
use std::thread::{self, JoinHandle};

use crossbeam_channel::{bounded, select, Receiver, Sender};

use crate::appender::syslog::{get_fallback_count, write_fatal_to_syslog};
use crate::appender::Appender;
use crate::error::Log4rError;
use crate::event::LogEvent;
use crate::level::Level;
use crate::log_internal_error;

/// 默认批量处理大小
pub const DEFAULT_BATCH_SIZE: usize = 100;

/// 默认批量超时时间（毫秒）
///
/// 当距上次写入超过此时间且批次非空时，强制刷新。
pub const DEFAULT_BATCH_TIMEOUT_MS: u64 = 100;

/// 默认关闭超时时间（秒）
pub const DEFAULT_SHUTDOWN_TIMEOUT_SECS: u64 = 5;

/// 工作线程配置
///
/// 配置后台工作线程的行为参数。
///
/// ## 字段
///
/// - `batch_size` - 每批处理的最大日志数量，默认 100
/// - `batch_timeout_ms` - 批量超时时间（毫秒），默认 100
///
/// ## 批量处理触发条件
///
/// 1. 累积日志数 >= `batch_size`
/// 2. 距上次写入 >= `batch_timeout_ms`（批次非空时）
/// 3. 收到 FATAL 级别日志（立即刷新）
/// 4. 收到关闭信号
///
/// ## 示例
///
/// ```rust
/// use log4r::async_rt::WorkerConfig;
///
/// // 使用默认配置
/// let config = WorkerConfig::default();
/// assert_eq!(config.batch_size, 100);
/// assert_eq!(config.batch_timeout_ms, 100);
///
/// // 自定义配置
/// let config = WorkerConfig {
///     batch_size: 50,
///     batch_timeout_ms: 200,
/// };
/// ```
#[derive(Debug, Clone)]
pub struct WorkerConfig {
    /// 批量处理大小：累积日志数达到此值时触发写入
    pub batch_size: usize,
    /// 批量超时时间（毫秒）：距上次写入超过此时间时强制刷新
    pub batch_timeout_ms: u64,
}

impl Default for WorkerConfig {
    fn default() -> Self {
        Self {
            batch_size: DEFAULT_BATCH_SIZE,
            batch_timeout_ms: DEFAULT_BATCH_TIMEOUT_MS,
        }
    }
}

/// 后台工作线程
///
/// 从消息队列消费日志事件，批量写入配置的 Appender。
/// 支持优雅关闭，等待队列中剩余事件处理完成。
///
/// ## 线程安全
///
/// `Worker` 实现了 `Send`，可以在线程间移动。
/// 但不实现 `Sync`，因为 `shutdown` 方法消费 self。
///
/// ## 生命周期
///
/// 1. 调用 `Worker::start()` 启动后台线程
/// 2. 后台线程持续消费队列中的日志事件
/// 3. 调用 `Worker::shutdown()` 发送关闭信号
/// 4. 后台线程处理完剩余事件后退出
///
/// ## 示例
///
/// ```rust,ignore
/// use log4r::async_rt::{LogChannel, Worker, WorkerConfig};
///
/// let channel = LogChannel::new(1000);
/// let worker = Worker::start(
///     channel.receiver().clone(),
///     vec![],
///     WorkerConfig::default(),
/// );
///
/// // ... 发送日志事件 ...
///
/// // 优雅关闭
/// worker.shutdown().unwrap();
/// ```
pub struct Worker {
    /// 线程句柄
    handle: Option<JoinHandle<()>>,
    /// 关闭信号发送端
    shutdown_sender: Sender<()>,
}

// 编译时断言：验证 Worker 实现 Send
const _: () = {
    const fn assert_send<T: Send>() {}
    assert_send::<Worker>();
};

impl Worker {
    /// 启动工作线程
    ///
    /// 创建后台线程，从 receiver 消费日志事件并写入 appenders。
    /// 线程使用 `catch_unwind` 保护，防止 panic 传播。
    /// 当主 Appender 写入失败时，会尝试降级到 fallback Appender。
    /// FATAL 级别日志会同步写入系统日志（双写机制）。
    ///
    /// # Arguments
    ///
    /// * `receiver` - 日志事件接收端
    /// * `appenders` - Appender 列表
    /// * `fallback` - Fallback Appender（通常为 stderr），用于错误降级
    /// * `config` - 工作线程配置
    /// * `app_name` - 应用名称，用于系统日志标识
    ///
    /// # Returns
    ///
    /// 返回 `Worker` 实例，用于管理线程生命周期。
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// use log4r::async_rt::{LogChannel, Worker, WorkerConfig};
    /// use log4r::appender::ConsoleAppender;
    ///
    /// let channel = LogChannel::new(1000);
    /// let fallback = Arc::new(ConsoleAppender::stderr());
    /// let worker = Worker::start(
    ///     channel.receiver().clone(),
    ///     vec![],
    ///     fallback,
    ///     WorkerConfig::default(),
    ///     "my_app".to_string(),
    /// );
    /// ```
    pub fn start(
        receiver: Receiver<LogEvent>,
        appenders: Vec<Arc<dyn Appender>>,
        fallback: Arc<dyn Appender>,
        config: WorkerConfig,
        app_name: String,
    ) -> Self {
        let (shutdown_sender, shutdown_receiver) = bounded::<()>(1);

        let handle = thread::spawn(move || {
            // 使用 catch_unwind 保护线程
            // AssertUnwindSafe 用于包装可能包含内部可变性的类型
            let result = std::panic::catch_unwind(AssertUnwindSafe(|| {
                Self::run_loop(
                    receiver,
                    shutdown_receiver,
                    appenders,
                    fallback,
                    config,
                    app_name,
                );
            }));

            if let Err(e) = result {
                // panic 时输出错误信息到 stderr（使用 log_internal_error 限流）
                log_internal_error(&format!("后台写入线程 panic: {:?}", e));
            }
        });

        Self {
            handle: Some(handle),
            shutdown_sender,
        }
    }

    /// 关闭工作线程
    ///
    /// 发送关闭信号，等待后台线程处理完剩余事件后退出。
    /// 如果等待超时（默认 5 秒），返回错误。
    ///
    /// # Returns
    ///
    /// * `Ok(())` - 关闭成功
    /// * `Err(Log4rError)` - 关闭失败（超时或线程 join 失败）
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// // 优雅关闭
    /// worker.shutdown().unwrap();
    /// ```
    pub fn shutdown(self) -> Result<(), Log4rError> {
        self.shutdown_with_timeout(std::time::Duration::from_secs(
            DEFAULT_SHUTDOWN_TIMEOUT_SECS,
        ))
    }

    /// 使用指定超时时间关闭工作线程
    ///
    /// # Arguments
    ///
    /// * `timeout` - 最大等待时间
    ///
    /// # Returns
    ///
    /// * `Ok(())` - 关闭成功
    /// * `Err(Log4rError)` - 关闭失败（超时或线程 join 失败）
    pub fn shutdown_with_timeout(mut self, timeout: std::time::Duration) -> Result<(), Log4rError> {
        // 发送关闭信号（忽略发送失败，可能接收端已关闭）
        let _ = self.shutdown_sender.send(());

        // 等待线程结束（带超时）
        if let Some(handle) = self.handle.take() {
            // 使用轮询方式实现超时等待
            let start = std::time::Instant::now();
            loop {
                if handle.is_finished() {
                    // 线程已结束，执行 join 获取结果
                    return handle.join().map_err(|_| Log4rError::AppenderError {
                        name: "Worker".to_string(),
                        cause: "线程 join 失败".to_string(),
                    });
                }

                if start.elapsed() >= timeout {
                    return Err(Log4rError::AppenderError {
                        name: "Worker".to_string(),
                        cause: format!("关闭超时（{}秒）", timeout.as_secs()),
                    });
                }

                // 短暂休眠避免忙等待
                std::thread::sleep(std::time::Duration::from_millis(10));
            }
        }

        Ok(())
    }

    /// 工作线程主循环
    ///
    /// 持续从 receiver 接收日志事件，批量处理后写入 appenders。
    ///
    /// ## 批量处理触发条件
    ///
    /// 1. 累积日志数 >= `batch_size` (AC-14.1.1)
    /// 2. 距上次写入 >= `batch_timeout_ms` 且批次非空 (AC-14.2.1)
    /// 3. 收到 FATAL 级别日志（立即刷新）(Story 14.3)
    /// 4. 收到关闭信号 (AC-14.1.3)
    ///
    /// ## 内存管理
    ///
    /// - 使用 `Vec::with_capacity(batch_size)` 预分配内存 (AC-14.1.2 #3)
    /// - 使用 `batch.clear()` 保留容量，避免重新分配 (AC-14.1.2 #4)
    fn run_loop(
        receiver: Receiver<LogEvent>,
        shutdown_receiver: Receiver<()>,
        appenders: Vec<Arc<dyn Appender>>,
        fallback: Arc<dyn Appender>,
        config: WorkerConfig,
        app_name: String,
    ) {
        use std::time::{Duration, Instant};

        // AC-14.1.2 #3: 使用 Vec::with_capacity(batch_size) 预分配内存
        let mut batch = Vec::with_capacity(config.batch_size);

        // AC-14.2.1 #1: 添加 last_flush 时间戳跟踪上次刷新时间
        let mut last_flush = Instant::now();

        // AC-14.2.1 #2: 计算超时时间
        let timeout = Duration::from_millis(config.batch_timeout_ms);

        loop {
            // AC-14.2.2 #2: 计算剩余超时时间
            let remaining = timeout.saturating_sub(last_flush.elapsed());

            select! {
                // 接收关闭信号
                recv(shutdown_receiver) -> _ => {
                    // AC-14.1.3 #5: 处理当前批次
                    if !batch.is_empty() {
                        Self::process_batch(&batch, &appenders, &fallback, &app_name);
                        Self::flush_all(&appenders);
                    }
                    // AC-14.1.3 #6: 清空队列中所有日志
                    Self::drain_queue(&receiver, &appenders, &fallback, &config, &app_name);
                    // 输出降级统计（如果有降级发生）
                    Self::report_fallback_stats();
                    // 关闭所有 Appender
                    Self::close_all(&appenders);
                    break;
                }
                // AC-14.2.1 #3: 超时触发刷新
                default(remaining) => {
                    // AC-14.2.1 #4: 超时时检查批次是否非空
                    if !batch.is_empty() {
                        // AC-14.2.1 #1: 批次非空，强制刷新
                        Self::process_batch(&batch, &appenders, &fallback, &app_name);
                        batch.clear();
                        Self::flush_all(&appenders);
                        // AC-14.2.3 #5: 刷新后重置计时器
                        last_flush = Instant::now();
                    }
                    // AC-14.2.1 #2: 批次为空，不执行任何操作，继续等待
                }
                // 接收日志事件
                recv(receiver) -> result => {
                    match result {
                        Ok(event) => {
                            // AC-14.3.1 #1, #2: 检测 FATAL 级别
                            let is_fatal = event.level == Level::Fatal;
                            batch.push(event);

                            // AC-14.3.1: FATAL 级别立即刷新，跳过批量收集
                            if is_fatal {
                                Self::process_batch(&batch, &appenders, &fallback, &app_name);
                                batch.clear();
                                Self::flush_all(&appenders);
                                // AC-14.3.2 #3: FATAL 刷新后重置计时器
                                last_flush = Instant::now();
                                continue; // 跳过批量收集，回到 select!
                            }

                            // AC-14.3.3 #4, #5: 批量收集（非阻塞），遇到 FATAL 立即退出
                            let mut batch_has_fatal = false;
                            while batch.len() < config.batch_size {
                                match receiver.try_recv() {
                                    Ok(e) => {
                                        let e_is_fatal = e.level == Level::Fatal;
                                        batch.push(e);
                                        // FATAL 在批量收集中也立即触发刷新
                                        if e_is_fatal {
                                            batch_has_fatal = true;
                                            break;
                                        }
                                    }
                                    Err(_) => break,
                                }
                            }

                            // AC-14.1.1 #1: 达到 batch_size 时触发写入
                            // AC-14.3.4 #6, #7: FATAL 优先于批量大小和超时触发
                            let should_flush = batch.len() >= config.batch_size || batch_has_fatal;

                            if should_flush {
                                // 处理批次（带错误隔离和降级，FATAL 双写）
                                Self::process_batch(&batch, &appenders, &fallback, &app_name);
                                // AC-14.1.2 #4: 调用 batch.clear() 保留容量
                                batch.clear();
                                // flush 所有 Appender
                                Self::flush_all(&appenders);
                                // AC-14.2.2 #1, #3: 刷新后重置计时器
                                last_flush = Instant::now();
                            }
                        }
                        Err(_) => {
                            // 发送端已断开
                            // 处理剩余批次
                            if !batch.is_empty() {
                                Self::process_batch(&batch, &appenders, &fallback, &app_name);
                                Self::flush_all(&appenders);
                            }
                            // 输出降级统计（如果有降级发生）
                            Self::report_fallback_stats();
                            Self::close_all(&appenders);
                            break;
                        }
                    }
                }
            }
        }
    }

    /// 处理一批日志事件（带错误隔离、降级和 FATAL 双写）
    ///
    /// 将批次中的每个事件写入所有 Appender。
    /// 实现错误隔离：
    /// - 当 Appender 写入失败时，记录错误并继续
    /// - 当所有主 Appender 都失败时，尝试降级到 fallback
    /// - 当 fallback 也失败时，静默忽略，继续处理后续事件
    /// - FATAL 级别日志同步写入系统日志（双写机制）
    ///
    /// # Arguments
    ///
    /// * `batch` - 要处理的日志事件批次
    /// * `appenders` - 主 Appender 列表
    /// * `fallback` - Fallback Appender（用于降级）
    /// * `app_name` - 应用名称，用于系统日志标识
    fn process_batch(
        batch: &[LogEvent],
        appenders: &[Arc<dyn Appender>],
        fallback: &Arc<dyn Appender>,
        app_name: &str,
    ) {
        for event in batch {
            Self::process_event(event, appenders, fallback, app_name);
        }
    }

    /// 处理单个日志事件（带错误隔离和 FATAL 双写）
    ///
    /// FATAL 级别日志会同步写入系统日志，然后写入正常 Appender。
    /// 两个写入操作相互独立，一个失败不影响另一个。
    /// 尝试写入所有主 Appender，如果全部失败则降级到 fallback。
    /// 所有错误都被捕获，不会导致 panic。
    ///
    /// # Arguments
    ///
    /// * `event` - 要处理的日志事件
    /// * `appenders` - 主 Appender 列表
    /// * `fallback` - Fallback Appender（用于降级）
    /// * `app_name` - 应用名称，用于系统日志标识
    fn process_event(
        event: &LogEvent,
        appenders: &[Arc<dyn Appender>],
        fallback: &Arc<dyn Appender>,
        app_name: &str,
    ) {
        // 1. FATAL 级别：同步写入系统日志（独立于正常 Appender）
        //    系统日志写入失败不影响正常 Appender 写入
        if event.level == Level::Fatal {
            write_fatal_to_syslog(event, app_name);
        }

        // 2. 正常 Appender 写入（独立于系统日志）
        //    正常 Appender 写入失败不影响系统日志写入
        let mut any_success = false;
        let mut errors: Vec<String> = Vec::new();

        // 尝试写入所有主 Appender
        for appender in appenders {
            match appender.write(event) {
                Ok(()) => any_success = true,
                Err(e) => {
                    errors.push(format!("{}", e));
                }
            }
        }

        // 如果所有主 Appender 都失败（且有主 Appender），尝试 fallback
        if !any_success && !appenders.is_empty() {
            // 记录错误到 stderr（带限流）
            log_internal_error(&format!(
                "所有 Appender 写入失败: {:?}，尝试降级到 stderr",
                errors
            ));

            // 尝试 fallback（静默处理错误）
            let _ = fallback.write(event);
        }
    }

    /// 清空队列中剩余事件
    ///
    /// 在关闭时调用，确保队列中所有事件都被处理。
    /// FATAL 级别日志会同步写入系统日志。
    fn drain_queue(
        receiver: &Receiver<LogEvent>,
        appenders: &[Arc<dyn Appender>],
        fallback: &Arc<dyn Appender>,
        config: &WorkerConfig,
        app_name: &str,
    ) {
        let mut batch = Vec::with_capacity(config.batch_size);

        while let Ok(event) = receiver.try_recv() {
            batch.push(event);

            if batch.len() >= config.batch_size {
                Self::process_batch(&batch, appenders, fallback, app_name);
                batch.clear();
                Self::flush_all(appenders);
            }
        }

        // 处理剩余事件
        if !batch.is_empty() {
            Self::process_batch(&batch, appenders, fallback, app_name);
            Self::flush_all(appenders);
        }
    }

    /// 刷新所有 Appender
    fn flush_all(appenders: &[Arc<dyn Appender>]) {
        for appender in appenders {
            if let Err(e) = appender.flush() {
                eprintln!("[log4r] Appender flush 失败: {}", e);
            }
        }
    }

    /// 关闭所有 Appender
    fn close_all(appenders: &[Arc<dyn Appender>]) {
        for appender in appenders {
            if let Err(e) = appender.close() {
                eprintln!("[log4r] Appender close 失败: {}", e);
            }
        }
    }

    /// 输出降级统计（如果有降级发生）
    ///
    /// 在 shutdown 时调用，报告会话期间系统日志降级的总次数。
    fn report_fallback_stats() {
        let count = get_fallback_count();
        if count > 0 {
            eprintln!(
                "[log4r] Session summary: {} FATAL log(s) fell back to stderr due to system log failures",
                count
            );
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::level::Level;
    use std::sync::Mutex;
    use std::time::Duration;

    /// 测试用 Mock Appender
    struct MockAppender {
        events: Arc<Mutex<Vec<String>>>,
        flush_count: Arc<Mutex<usize>>,
        close_count: Arc<Mutex<usize>>,
    }

    impl MockAppender {
        fn new() -> Self {
            Self {
                events: Arc::new(Mutex::new(Vec::new())),
                flush_count: Arc::new(Mutex::new(0)),
                close_count: Arc::new(Mutex::new(0)),
            }
        }

        fn events_clone(&self) -> Arc<Mutex<Vec<String>>> {
            Arc::clone(&self.events)
        }

        fn flush_count_clone(&self) -> Arc<Mutex<usize>> {
            Arc::clone(&self.flush_count)
        }

        fn close_count_clone(&self) -> Arc<Mutex<usize>> {
            Arc::clone(&self.close_count)
        }
    }

    impl Appender for MockAppender {
        fn write(&self, event: &LogEvent) -> Result<(), Log4rError> {
            self.events
                .lock()
                .map_err(|_| Log4rError::appender("MockAppender", "获取锁失败"))?
                .push(format!("[{}] {}", event.level, event.message));
            Ok(())
        }

        fn flush(&self) -> Result<(), Log4rError> {
            let mut count = self
                .flush_count
                .lock()
                .map_err(|_| Log4rError::appender("MockAppender", "获取锁失败"))?;
            *count += 1;
            Ok(())
        }

        fn close(&self) -> Result<(), Log4rError> {
            let mut count = self
                .close_count
                .lock()
                .map_err(|_| Log4rError::appender("MockAppender", "获取锁失败"))?;
            *count += 1;
            Ok(())
        }
    }

    // UT-6.2-001: 测试 WorkerConfig 默认值
    #[test]
    fn test_worker_config_default() {
        // GIVEN/WHEN: 创建默认配置
        let config = WorkerConfig::default();

        // THEN: 默认值应正确
        assert_eq!(config.batch_size, DEFAULT_BATCH_SIZE);
        assert_eq!(config.batch_size, 100);
        assert_eq!(config.batch_timeout_ms, DEFAULT_BATCH_TIMEOUT_MS);
        assert_eq!(config.batch_timeout_ms, 100);
    }

    // UT-6.2-002: 测试 Worker::start() 线程启动
    #[test]
    fn test_worker_start_creates_thread() {
        // GIVEN: 创建 channel 和空 appenders
        let (sender, receiver) = bounded::<LogEvent>(100);
        let appenders: Vec<Arc<dyn Appender>> = vec![];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        // WHEN: 启动 Worker
        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            WorkerConfig::default(),
            "test_app".to_string(),
        );

        // THEN: Worker 应有有效的 handle
        assert!(worker.handle.is_some());

        // 清理：关闭 Worker
        drop(sender); // 断开发送端
        let result = worker.shutdown();
        assert!(result.is_ok());
    }

    // UT-6.2-003: 测试 process_batch() 批量处理逻辑
    #[test]
    fn test_process_batch_writes_to_appenders() {
        // GIVEN: Mock Appender 和一批事件
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let batch = vec![
            LogEvent::new(Level::Info, "test", "msg1"),
            LogEvent::new(Level::Warn, "test", "msg2"),
            LogEvent::new(Level::Error, "test", "msg3"),
        ];

        // WHEN: 处理批次
        Worker::process_batch(&batch, &appenders, &fallback, "test_app");

        // THEN: 所有事件应被写入
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 3);
        assert!(events[0].contains("msg1"));
        assert!(events[1].contains("msg2"));
        assert!(events[2].contains("msg3"));
    }

    // UT-6.2-004: 测试 Worker::shutdown() 优雅关闭
    #[test]
    fn test_worker_shutdown_graceful() {
        // GIVEN: 启动 Worker
        let (sender, receiver) = bounded::<LogEvent>(100);
        let mock = MockAppender::new();
        let close_count_ref = mock.close_count_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            WorkerConfig::default(),
            "test_app".to_string(),
        );

        // 发送一些事件
        for i in 0..5 {
            let event = LogEvent::new(Level::Info, "test", format!("msg{}", i));
            sender.send(event).unwrap_or(());
        }

        // 给 Worker 一点时间处理
        thread::sleep(Duration::from_millis(50));

        // WHEN: 关闭 Worker
        drop(sender);
        let result = worker.shutdown();

        // THEN: 关闭应成功，close 应被调用
        assert!(result.is_ok());
        let close_count = *close_count_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(close_count, 1);
    }

    // UT-6.2-005: 测试 flush_all 被调用
    #[test]
    fn test_flush_all_called_after_batch() {
        // GIVEN: Mock Appender
        let mock = MockAppender::new();
        let flush_count_ref = mock.flush_count_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];

        // WHEN: 调用 flush_all
        Worker::flush_all(&appenders);

        // THEN: flush 应被调用
        let flush_count = *flush_count_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(flush_count, 1);
    }

    // UT-6.2-006: 测试 close_all 被调用
    #[test]
    fn test_close_all_called_on_shutdown() {
        // GIVEN: Mock Appender
        let mock = MockAppender::new();
        let close_count_ref = mock.close_count_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];

        // WHEN: 调用 close_all
        Worker::close_all(&appenders);

        // THEN: close 应被调用
        let close_count = *close_count_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(close_count, 1);
    }

    // UT-6.2-007: 测试 drain_queue 清空队列
    #[test]
    fn test_drain_queue_processes_remaining_events() {
        // GIVEN: 有事件的队列
        let (sender, receiver) = bounded::<LogEvent>(100);
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());
        let config = WorkerConfig::default();

        // 发送事件
        for i in 0..5 {
            let event = LogEvent::new(Level::Info, "test", format!("drain{}", i));
            sender.send(event).unwrap_or(());
        }

        // WHEN: 清空队列
        Worker::drain_queue(&receiver, &appenders, &fallback, &config, "test_app");

        // THEN: 所有事件应被处理
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 5);
    }

    // UT-6.2-008: 测试 Worker 实现 Send
    #[test]
    fn test_worker_is_send() {
        fn assert_send<T: Send>() {}
        assert_send::<Worker>();
    }

    // UT-6.2-009: 测试常量值
    #[test]
    fn test_constants() {
        assert_eq!(DEFAULT_BATCH_SIZE, 100);
        assert_eq!(DEFAULT_SHUTDOWN_TIMEOUT_SECS, 5);
    }

    // UT-6.2-010: 测试多个 Appender
    #[test]
    fn test_multiple_appenders() {
        // GIVEN: 多个 Mock Appender
        let mock1 = MockAppender::new();
        let mock2 = MockAppender::new();
        let events1 = mock1.events_clone();
        let events2 = mock2.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock1), Arc::new(mock2)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let batch = vec![LogEvent::new(Level::Info, "test", "multi")];

        // WHEN: 处理批次
        Worker::process_batch(&batch, &appenders, &fallback, "test_app");

        // THEN: 两个 Appender 都应收到事件
        assert_eq!(events1.lock().unwrap_or_else(|e| e.into_inner()).len(), 1);
        assert_eq!(events2.lock().unwrap_or_else(|e| e.into_inner()).len(), 1);
    }

    // =========================================================================
    // Story 7.6: 错误隔离和降级单元测试
    // =========================================================================

    /// 可配置失败的 Mock Appender
    struct FailingAppender {
        /// 是否应该失败
        should_fail: std::sync::atomic::AtomicBool,
        /// 写入计数
        write_count: std::sync::atomic::AtomicU64,
    }

    impl FailingAppender {
        fn new(should_fail: bool) -> Self {
            Self {
                should_fail: std::sync::atomic::AtomicBool::new(should_fail),
                write_count: std::sync::atomic::AtomicU64::new(0),
            }
        }
    }

    impl Appender for FailingAppender {
        fn write(&self, _event: &LogEvent) -> Result<(), Log4rError> {
            self.write_count
                .fetch_add(1, std::sync::atomic::Ordering::SeqCst);
            if self.should_fail.load(std::sync::atomic::Ordering::SeqCst) {
                Err(Log4rError::AppenderError {
                    name: "FailingAppender".to_string(),
                    cause: "模拟写入失败".to_string(),
                })
            } else {
                Ok(())
            }
        }

        fn flush(&self) -> Result<(), Log4rError> {
            Ok(())
        }
        fn close(&self) -> Result<(), Log4rError> {
            Ok(())
        }
    }

    // UT-7.6-001: 测试 Appender 写入失败时不 panic (AC-7.6.1)
    #[test]
    fn test_appender_write_failure_no_panic() {
        // GIVEN: 会失败的 Appender
        let failing = FailingAppender::new(true);
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(failing)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let event = LogEvent::new(Level::Info, "test", "test message");

        // WHEN: 处理事件（不应 panic）
        Worker::process_event(&event, &appenders, &fallback, "test_app");

        // THEN: 不应 panic，测试通过即验证成功
    }

    // UT-7.6-002: 测试降级到 fallback Appender (AC-7.6.1)
    #[test]
    fn test_fallback_on_all_appenders_fail() {
        // GIVEN: 会失败的主 Appender 和正常的 fallback
        let failing = FailingAppender::new(true);
        let fallback_mock = MockAppender::new();
        let fallback_events = fallback_mock.events_clone();

        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(failing)];
        let fallback: Arc<dyn Appender> = Arc::new(fallback_mock);

        let event = LogEvent::new(Level::Error, "test", "fallback test");

        // WHEN: 处理事件
        Worker::process_event(&event, &appenders, &fallback, "test_app");

        // THEN: fallback 应收到事件
        let events = fallback_events.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 1);
        assert!(events[0].contains("fallback test"));
    }

    // UT-7.6-003: 测试所有 Appender 失败时静默处理 (AC-7.6.2)
    #[test]
    fn test_silent_on_all_fail_including_fallback() {
        // GIVEN: 所有 Appender 都会失败
        let failing_main = FailingAppender::new(true);
        let failing_fallback = FailingAppender::new(true);

        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(failing_main)];
        let fallback: Arc<dyn Appender> = Arc::new(failing_fallback);

        let event = LogEvent::new(Level::Fatal, "test", "all fail test");

        // WHEN: 处理事件（不应 panic）
        Worker::process_event(&event, &appenders, &fallback, "test_app");

        // THEN: 不应 panic，静默处理，测试通过即验证成功
    }

    // UT-7.6-004: 测试部分 Appender 成功时不触发 fallback (AC-7.6.1)
    #[test]
    fn test_no_fallback_when_some_succeed() {
        // GIVEN: 一个成功一个失败的 Appender
        let success_mock = MockAppender::new();
        let success_events = success_mock.events_clone();
        let failing = FailingAppender::new(true);
        let fallback_mock = MockAppender::new();
        let fallback_events = fallback_mock.events_clone();

        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(success_mock), Arc::new(failing)];
        let fallback: Arc<dyn Appender> = Arc::new(fallback_mock);

        let event = LogEvent::new(Level::Info, "test", "partial success");

        // WHEN: 处理事件
        Worker::process_event(&event, &appenders, &fallback, "test_app");

        // THEN: 成功的 Appender 应收到事件，fallback 不应被调用
        let success = success_events.lock().unwrap_or_else(|e| e.into_inner());
        let fallback_evts = fallback_events.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(success.len(), 1);
        assert_eq!(fallback_evts.len(), 0);
    }

    // UT-7.6-005: 测试空 Appender 列表不触发 fallback (AC-7.6.1)
    #[test]
    fn test_empty_appenders_no_fallback() {
        // GIVEN: 空的 Appender 列表
        let appenders: Vec<Arc<dyn Appender>> = vec![];
        let fallback_mock = MockAppender::new();
        let fallback_events = fallback_mock.events_clone();
        let fallback: Arc<dyn Appender> = Arc::new(fallback_mock);

        let event = LogEvent::new(Level::Info, "test", "empty appenders");

        // WHEN: 处理事件
        Worker::process_event(&event, &appenders, &fallback, "test_app");

        // THEN: fallback 不应被调用（因为没有主 Appender 失败）
        let fallback_evts = fallback_events.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(fallback_evts.len(), 0);
    }

    // UT-7.6-006: 测试 process_batch 批量处理带错误隔离 (AC-7.6.1, AC-7.6.2)
    #[test]
    fn test_process_batch_with_error_isolation() {
        // GIVEN: 会失败的 Appender 和多个事件
        let failing = FailingAppender::new(true);
        let fallback_mock = MockAppender::new();
        let fallback_events = fallback_mock.events_clone();

        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(failing)];
        let fallback: Arc<dyn Appender> = Arc::new(fallback_mock);

        let batch = vec![
            LogEvent::new(Level::Info, "test", "batch1"),
            LogEvent::new(Level::Warn, "test", "batch2"),
            LogEvent::new(Level::Error, "test", "batch3"),
        ];

        // WHEN: 处理批次
        Worker::process_batch(&batch, &appenders, &fallback, "test_app");

        // THEN: 所有事件都应降级到 fallback
        let fallback_evts = fallback_events.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(fallback_evts.len(), 3);
    }

    // =========================================================================
    // Story 8.4: FATAL 双写机制单元测试
    // =========================================================================

    // UT-8.4-001: 测试 FATAL 级别触发系统日志写入 (AC-8.4.2)
    #[test]
    fn test_fatal_level_triggers_syslog_write() {
        // GIVEN: Mock Appender 和 FATAL 事件
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let event = LogEvent::new(Level::Fatal, "test", "fatal error");

        // WHEN: 处理 FATAL 事件
        Worker::process_event(&event, &appenders, &fallback, "test_app");

        // THEN: 正常 Appender 应收到事件（系统日志写入在平台层验证）
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 1);
        assert!(events[0].contains("fatal error"));
    }

    // UT-8.4-002: 测试非 FATAL 级别不触发系统日志写入 (AC-8.4.2)
    #[test]
    fn test_non_fatal_levels_no_syslog_write() {
        // GIVEN: 非 FATAL 级别事件
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let levels = [
            Level::Trace,
            Level::Debug,
            Level::Info,
            Level::Warn,
            Level::Error,
        ];

        for level in levels {
            let event = LogEvent::new(level, "test", "message");

            // WHEN: 处理非 FATAL 事件
            Worker::process_event(&event, &appenders, &fallback, "test_app");
        }

        // THEN: 所有事件应写入正常 Appender
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 5);
    }

    // UT-8.4-004: 测试系统日志失败不影响正常 Appender (AC-8.4.4)
    #[test]
    fn test_syslog_failure_does_not_affect_normal_appender() {
        // GIVEN: 正常的 Mock Appender
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let event = LogEvent::new(Level::Fatal, "test", "fatal with syslog failure");

        // WHEN: 处理 FATAL 事件（系统日志可能失败，但不影响正常 Appender）
        Worker::process_event(&event, &appenders, &fallback, "test_app");

        // THEN: 正常 Appender 应收到事件
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 1);
        assert!(events[0].contains("fatal with syslog failure"));
    }

    // UT-8.4-005: 测试正常 Appender 失败不影响系统日志 (AC-8.4.4)
    #[test]
    fn test_normal_appender_failure_does_not_affect_syslog() {
        // GIVEN: 会失败的 Appender
        let failing = FailingAppender::new(true);
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(failing)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let event = LogEvent::new(Level::Fatal, "test", "fatal with appender failure");

        // WHEN: 处理 FATAL 事件（正常 Appender 失败，但系统日志应独立写入）
        // 不应 panic
        Worker::process_event(&event, &appenders, &fallback, "test_app");

        // THEN: 测试通过即验证成功（系统日志写入独立于正常 Appender）
    }

    // UT-8.4-006: 测试 FATAL 同时写入两个目标 (AC-8.4.1, AC-8.4.2)
    #[test]
    fn test_fatal_writes_to_both_targets() {
        // GIVEN: Mock Appender 和 FATAL 事件
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let event = LogEvent::new(Level::Fatal, "test", "dual write test");

        // WHEN: 处理 FATAL 事件
        Worker::process_event(&event, &appenders, &fallback, "test_app");

        // THEN: 正常 Appender 应收到事件
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 1);
        assert!(events[0].contains("dual write test"));
        // 系统日志写入在平台层验证（Windows/Linux/macOS）
    }

    // =========================================================================
    // Story 14.1: 批量写入缓冲测试
    // =========================================================================

    // UT-14.1-001: 测试批量大小触发写入 (AC-14.1.1 #1)
    #[test]
    fn test_batch_size_triggers_write() {
        // GIVEN: 配置 batch_size = 10
        let (sender, receiver) = bounded::<LogEvent>(100);
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let flush_count_ref = mock.flush_count_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let config = WorkerConfig {
            batch_size: 10,
            batch_timeout_ms: 10000, // 长超时，确保不触发
        };

        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            config,
            "test_app".to_string(),
        );

        // WHEN: 发送 10 条日志（达到 batch_size）
        for i in 0..10 {
            let event = LogEvent::new(Level::Info, "test", format!("msg{}", i));
            sender.send(event).unwrap_or(());
        }

        // 等待处理
        thread::sleep(Duration::from_millis(100));

        // THEN: 应触发一次批量写入
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 10, "应收到 10 条日志");

        let flush_count = *flush_count_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert!(flush_count >= 1, "flush 应至少被调用 1 次");

        // 清理
        drop(sender);
        let _ = worker.shutdown();
    }

    // UT-14.1-002: 测试未达到批量大小时，只有 shutdown 才处理 (AC-14.1.1 #2)
    #[test]
    fn test_batch_not_trigger_below_size() {
        // GIVEN: 配置 batch_size = 100
        let (sender, receiver) = bounded::<LogEvent>(100);
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let config = WorkerConfig {
            batch_size: 100,
            batch_timeout_ms: 10000, // 长超时
        };

        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            config,
            "test_app".to_string(),
        );

        // WHEN: 发送 50 条日志（未达到 batch_size）
        for i in 0..50 {
            let event = LogEvent::new(Level::Info, "test", format!("msg{}", i));
            sender.send(event).unwrap_or(());
        }

        // 等待事件进入队列
        thread::sleep(Duration::from_millis(50));

        // AND: 调用 shutdown（此时应处理剩余批次）
        drop(sender);
        let _ = worker.shutdown();

        // THEN: shutdown 后应处理所有 50 条事件
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 50, "shutdown 后应处理所有剩余事件");
    }

    // UT-14.1-003: 测试缓冲区预分配 (AC-14.1.2 #3)
    #[test]
    fn test_batch_buffer_preallocated() {
        // GIVEN: WorkerConfig 配置
        let config = WorkerConfig {
            batch_size: 100,
            batch_timeout_ms: 100,
        };

        // WHEN: 创建预分配的缓冲区
        let batch: Vec<LogEvent> = Vec::with_capacity(config.batch_size);

        // THEN: 容量应为 batch_size
        assert_eq!(batch.capacity(), 100);
        assert_eq!(batch.len(), 0);
    }

    // UT-14.1-004: 测试 clear() 保留容量 (AC-14.1.2 #4)
    #[test]
    fn test_batch_clear_preserves_capacity() {
        // GIVEN: 预分配的缓冲区并添加元素
        let mut batch: Vec<LogEvent> = Vec::with_capacity(100);
        for i in 0..50 {
            batch.push(LogEvent::new(Level::Info, "test", format!("msg{}", i)));
        }
        assert_eq!(batch.len(), 50);
        assert!(batch.capacity() >= 100);

        // WHEN: 调用 clear()
        batch.clear();

        // THEN: 长度为 0，但容量保持
        assert_eq!(batch.len(), 0);
        assert!(batch.capacity() >= 100, "clear() 应保留容量");
    }

    // UT-14.1-005: 测试关闭时处理当前批次 (AC-14.1.3 #5)
    #[test]
    fn test_shutdown_processes_current_batch() {
        // GIVEN: 配置 batch_size = 100
        let (sender, receiver) = bounded::<LogEvent>(100);
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let close_count_ref = mock.close_count_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let config = WorkerConfig {
            batch_size: 100,
            batch_timeout_ms: 10000, // 长超时
        };

        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            config,
            "test_app".to_string(),
        );

        // WHEN: 发送 30 条日志（未达到 batch_size）
        for i in 0..30 {
            let event = LogEvent::new(Level::Info, "test", format!("shutdown_msg{}", i));
            sender.send(event).unwrap_or(());
        }

        // 等待事件进入队列
        thread::sleep(Duration::from_millis(50));

        // AND: 调用 shutdown
        drop(sender);
        let result = worker.shutdown();

        // THEN: 关闭应成功，所有 30 条日志应被处理
        assert!(result.is_ok(), "shutdown 应成功");

        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 30, "shutdown 时应处理当前批次中的所有日志");

        let close_count = *close_count_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(close_count, 1, "close 应被调用");
    }

    // UT-14.1-006: 测试关闭时清空队列 (AC-14.1.3 #6)
    #[test]
    fn test_shutdown_drains_queue_completely() {
        // GIVEN: 配置 batch_size = 10
        let (sender, receiver) = bounded::<LogEvent>(200);
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let config = WorkerConfig {
            batch_size: 10,
            batch_timeout_ms: 10000, // 长超时
        };

        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            config,
            "test_app".to_string(),
        );

        // WHEN: 快速发送 55 条日志
        for i in 0..55 {
            let event = LogEvent::new(Level::Info, "test", format!("drain_msg{}", i));
            sender.send(event).unwrap_or(());
        }

        // 立即关闭（队列中可能还有未处理的事件）
        drop(sender);
        let result = worker.shutdown();

        // THEN: 关闭应成功，所有 55 条日志应被处理
        assert!(result.is_ok(), "shutdown 应成功");

        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 55, "shutdown 时应清空队列中所有日志");
    }

    // UT-14.1-007: 测试常量值
    #[test]
    fn test_batch_constants() {
        assert_eq!(DEFAULT_BATCH_SIZE, 100);
        assert_eq!(DEFAULT_BATCH_TIMEOUT_MS, 100);
    }

    // =========================================================================
    // Story 14.3: FATAL 立即刷新单元测试
    // =========================================================================

    // UT-14.3-001: 测试 FATAL 立即刷新（批次非空）(AC-14.3.1 #1)
    #[test]
    fn test_fatal_immediate_flush_with_pending_batch() {
        // GIVEN: Worker 配置大批量大小和长超时
        let (sender, receiver) = bounded::<LogEvent>(200);
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let flush_count_ref = mock.flush_count_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let config = WorkerConfig {
            batch_size: 100,         // 大批量大小
            batch_timeout_ms: 10000, // 长超时，确保不会超时触发
        };

        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            config,
            "test_app".to_string(),
        );

        // WHEN: 发送 50 条 INFO + 1 条 FATAL
        for i in 0..50 {
            let event = LogEvent::new(Level::Info, "test", format!("info_{}", i));
            sender.send(event).unwrap_or(());
        }
        let fatal_event = LogEvent::new(Level::Fatal, "test", "fatal_message");
        sender.send(fatal_event).unwrap_or(());

        // 等待处理
        thread::sleep(Duration::from_millis(100));

        // THEN: 所有 51 条日志应立即被写入
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(
            events.len(),
            51,
            "FATAL 应触发立即刷新，包含所有 50 条 INFO + 1 条 FATAL"
        );
        assert!(events
            .last()
            .unwrap_or(&String::new())
            .contains("fatal_message"));

        // flush 应被调用
        let flush_count = *flush_count_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert!(flush_count >= 1, "FATAL 应触发 flush");

        // 清理
        drop(sender);
        let _ = worker.shutdown();
    }

    // UT-14.3-002: 测试 FATAL 立即刷新（批次为空）(AC-14.3.1 #2)
    #[test]
    fn test_fatal_immediate_flush_empty_batch() {
        // GIVEN: Worker 配置大批量大小和长超时
        let (sender, receiver) = bounded::<LogEvent>(100);
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let flush_count_ref = mock.flush_count_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let config = WorkerConfig {
            batch_size: 100,
            batch_timeout_ms: 10000,
        };

        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            config,
            "test_app".to_string(),
        );

        // WHEN: 直接发送 FATAL（批次为空）
        let fatal_event = LogEvent::new(Level::Fatal, "test", "fatal_only");
        sender.send(fatal_event).unwrap_or(());

        // 等待处理
        thread::sleep(Duration::from_millis(100));

        // THEN: FATAL 应立即被写入
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 1, "单条 FATAL 应立即写入");
        assert!(events[0].contains("fatal_only"));

        let flush_count = *flush_count_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert!(flush_count >= 1, "FATAL 应触发 flush");

        // 清理
        drop(sender);
        let _ = worker.shutdown();
    }

    // UT-14.3-003: 测试 FATAL 刷新后计时器重置 (AC-14.3.2 #3)
    #[test]
    fn test_fatal_flush_resets_timer() {
        // GIVEN: Worker 配置短超时
        let (sender, receiver) = bounded::<LogEvent>(100);
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let config = WorkerConfig {
            batch_size: 100,
            batch_timeout_ms: 200, // 200ms 超时
        };

        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            config,
            "test_app".to_string(),
        );

        // WHEN: 发送 FATAL，然后发送 INFO
        let fatal_event = LogEvent::new(Level::Fatal, "test", "fatal_reset");
        sender.send(fatal_event).unwrap_or(());

        // 等待 FATAL 处理
        thread::sleep(Duration::from_millis(50));

        // 发送 INFO（此时计时器应已重置）
        let info_event = LogEvent::new(Level::Info, "test", "info_after_fatal");
        sender.send(info_event).unwrap_or(());

        // 等待超时触发（200ms）
        thread::sleep(Duration::from_millis(300));

        // THEN: 两条日志都应被写入（FATAL 立即，INFO 超时后）
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 2, "FATAL 和 INFO 都应被写入");

        // 清理
        drop(sender);
        let _ = worker.shutdown();
    }

    // UT-14.3-004: 测试批量收集中遇到 FATAL (AC-14.3.3 #4, #5)
    #[test]
    fn test_fatal_in_batch_collection() {
        // GIVEN: Worker 配置大批量大小
        let (sender, receiver) = bounded::<LogEvent>(200);
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let config = WorkerConfig {
            batch_size: 100,
            batch_timeout_ms: 10000,
        };

        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            config,
            "test_app".to_string(),
        );

        // WHEN: 快速发送多条日志，中间包含 FATAL
        for i in 0..30 {
            let event = LogEvent::new(Level::Info, "test", format!("batch_info_{}", i));
            sender.send(event).unwrap_or(());
        }
        let fatal_event = LogEvent::new(Level::Fatal, "test", "batch_fatal");
        sender.send(fatal_event).unwrap_or(());
        for i in 0..20 {
            let event = LogEvent::new(Level::Info, "test", format!("after_fatal_{}", i));
            sender.send(event).unwrap_or(());
        }

        // 等待处理
        thread::sleep(Duration::from_millis(200));

        // THEN: 所有日志应被处理（FATAL 触发刷新后继续正常处理）
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        // 至少应包含 FATAL 之前的日志 + FATAL
        assert!(events.len() >= 31, "FATAL 应触发刷新，至少包含 31 条日志");
        assert!(
            events.iter().any(|e| e.contains("batch_fatal")),
            "应包含 FATAL 日志"
        );

        // 清理
        drop(sender);
        let _ = worker.shutdown();
    }

    // UT-14.3-005: 测试 FATAL 优先于批量大小触发 (AC-14.3.4 #6)
    #[test]
    fn test_fatal_priority_over_batch_size() {
        // GIVEN: Worker 配置 batch_size = 100
        let (sender, receiver) = bounded::<LogEvent>(200);
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let flush_count_ref = mock.flush_count_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let config = WorkerConfig {
            batch_size: 100,
            batch_timeout_ms: 10000,
        };

        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            config,
            "test_app".to_string(),
        );

        // WHEN: 发送 99 条 INFO + 1 条 FATAL（未达到 batch_size）
        for i in 0..99 {
            let event = LogEvent::new(Level::Info, "test", format!("info_{}", i));
            sender.send(event).unwrap_or(());
        }
        let fatal_event = LogEvent::new(Level::Fatal, "test", "fatal_priority");
        sender.send(fatal_event).unwrap_or(());

        // 等待处理
        thread::sleep(Duration::from_millis(100));

        // THEN: 所有 100 条日志应立即被写入（FATAL 触发，不等待达到 100 条）
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(
            events.len(),
            100,
            "FATAL 应触发立即刷新，不等待达到 batch_size"
        );

        let flush_count = *flush_count_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert!(flush_count >= 1, "FATAL 应触发 flush");

        // 清理
        drop(sender);
        let _ = worker.shutdown();
    }

    // UT-14.3-006: 测试 FATAL 优先于超时触发 (AC-14.3.4 #7)
    #[test]
    fn test_fatal_priority_over_timeout() {
        // GIVEN: Worker 配置 100ms 超时
        let (sender, receiver) = bounded::<LogEvent>(100);
        let mock = MockAppender::new();
        let events_ref = mock.events_clone();
        let appenders: Vec<Arc<dyn Appender>> = vec![Arc::new(mock)];
        let fallback: Arc<dyn Appender> = Arc::new(MockAppender::new());

        let config = WorkerConfig {
            batch_size: 100,
            batch_timeout_ms: 500, // 500ms 超时
        };

        let worker = Worker::start(
            receiver,
            appenders,
            fallback,
            config,
            "test_app".to_string(),
        );

        // WHEN: 发送 INFO，然后立即发送 FATAL（在超时前）
        let info_event = LogEvent::new(Level::Info, "test", "info_before_fatal");
        sender.send(info_event).unwrap_or(());

        // 等待 50ms（远小于 500ms 超时）
        thread::sleep(Duration::from_millis(50));

        let fatal_event = LogEvent::new(Level::Fatal, "test", "fatal_before_timeout");
        sender.send(fatal_event).unwrap_or(());

        // 等待处理（但不等待超时）
        thread::sleep(Duration::from_millis(100));

        // THEN: 两条日志应立即被写入（FATAL 触发，不等待超时）
        let events = events_ref.lock().unwrap_or_else(|e| e.into_inner());
        assert_eq!(events.len(), 2, "FATAL 应触发立即刷新，不等待超时");
        assert!(events.iter().any(|e| e.contains("fatal_before_timeout")));

        // 清理
        drop(sender);
        let _ = worker.shutdown();
    }
}
